module Duplicates

import List;
import IO;
import String;
import LinesOfCode;
import util::Math;

public int GetDuplicatesPercentage(list[loc] files)
{
	list[str] lines = ([] | it + ExtractLinesOfCode(f)| loc f <- files),temp = lines;
	list[list[str]] listBlocks = makeBLocksOfCode(lines),duplicates = [];
	
	int total = CountTotalLinesOfCode(files);
	for(int i <- [0..size(listBlocks)-1])
	{
		if(listBlocks[i] notin duplicates)
			duplicates += [listBlocks[i]];
		else
			lines = deleteFromLines(lines,i); 
	}
	
	return percent((size(temp - lines)),total);
}

private list[str] ExtractLinesOfCode(loc location)
{
	bool go = true;
	list[str] result = [];
	
	for(line <- readFileLines(location))
	{
		str trimmedLine = trim(line);
		
		if(trimmedLine != "")
		{
			if(trimmedLine !=  "{" && trimmedLine !=  "}")
			{
				if(startsWith(trimmedLine, "/*"))
					go = false;
				
				if(!startsWith(trimmedLine,"/") && !startsWith(trimmedLine,"*"))
	 				if(go)
						result += trimmedLine;
				
				if(endsWith(trimmedLine, "*/"))
					go = true;
			}
		}
	}
	return result;
}

private list[list[str]] makeBLocksOfCode(list[str] lines)
{
	list[list[str]] result = [];
	list[str] newLines = lines;

	for(int i <- [0..size(lines)-6])
	{
		result += [take(6,newLines)];
		newLines = drop(1,newLines);
	}
	return result;
}

private list[str] deleteFromLines(list[str] lines,int index)
{
	list[str] result = lines;

	for(int i <- [0..5])
	{
		if(size(result) >= 6)
		{
			result[index] = "";
			index += 1;
		}
	}
	return result;
}

public str GetDuplicatesScore(int duplicates)
{
	str operator = "";
	
	if(duplicates <= 3)
		operator = "++";
	else if(duplicates <= 5)
		operator = "+";
	else if(duplicates <= 10)
		operator = "o";
	else if(duplicates <= 20)
		operator = "-";
	else
		operator = "--";
	return operator;
}